<?php

namespace app\api\service;
/*
 * 支付宝支付接口
 * 新版本需要引入官网sdk包 , 老版本无需第三方sdk包
 * */
require_once (EXTEND_PATH.'alipay03/AopSdk.php'); // 新版本引入官网sdk包
class AliPay
{

    /**
     *生成APP支付订单信息
     * @param string $orderId 商品订单ID
     * @param string $subject 支付商品的标题
     * @param string $body 支付商品描述
     * @param float $pre_price 商品总支付金额
     * @param int $expire 支付交易时间
     * @return bool|string 返回支付宝签名后订单信息，否则返回false
     */
    public function unifiedorder($orderId, $subject,$body,$pre_price,$expire){

            /*支付宝老版本(2016年8月)*/
            $mygoods['partner'] = '"'.config('text.qnm_aliapy_partner').'"';
            $mygoods['seller_id'] = '"'.config('text.qnm_alipay_sellerid').'"';
            $mygoods['out_trade_no'] = '"'.$orderId.'"';
            $mygoods['subject'] = '"'.$subject.'"';
            $mygoods['body'] = '"'.$body.'"';
            $mygoods['total_fee'] = '"'.$pre_price.'"';
            $mygoods['notify_url'] = '"'.config('text.qnm_aliacall_url').'"';
            $mygoods['service'] = "\"mobile.securitypay.pay\"";
            $mygoods['payment_type'] = "\"1\"";
            $mygoods['_input_charset'] = "\"utf-8\"";
            $mygoods['it_b_pay'] = "\"30m\"";

            // 数组拼接成字符串
            $mystr = $this->createLinkstring($mygoods);
            //生成最终签名信息
            $sign = $this->rsaSign($mystr,'/home/canmay/www/test.qunarmeic.com/public/key/alia_prikey.pem');
            $sign = urlencode($sign);
            //生成最终签名信息
            $rest = $mystr.'&sign="'.$sign.'"&sign_type="RSA"';
            return $rest;

            /*支付宝新版本,通过sdk接入*/
            $aop = new \AopClient();
            $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
            $aop->appId = config('alia_pay.appid');
            $aop->rsaPrivateKey = config('alia_pay.private_key');
            $aop->format = "json";
            $aop->charset = "UTF-8";
            $aop->signType = "RSA2";
            $aop->alipayrsaPublicKey = config('alia_pay.public_key');
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
            $request = new \AlipayTradeAppPayRequest();
            //SDK已经封装掉了公共参数，这里只需要传入业务参数
            $bizcontent = "{\"body\":\"{$body}\"," //支付商品描述
                . "\"subject\":\"{$subject}\"," //支付商品的标题
                . "\"out_trade_no\":\"{$orderId}\"," //商户网站唯一订单号
                . "\"timeout_express\":\"{$expire}m\"," //该笔订单允许的最晚付款时间，逾期将关闭交易
                . "\"total_amount\":\"{$pre_price}\"," //订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]
                . "\"product_code\":\"QUICK_MSECURITY_PAY\""
                . "}";
            $request->setNotifyUrl(config('alia_pay.notify_url'));
            $request->setBizContent($bizcontent);
            //这里和普通的接口调用不同，使用的是sdkExecute
            $response = $aop->sdkExecute($request);
            //htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义，实际打印到日志以及http传输不会有这个问题
            return $response;
    }

    /*************************需要使用到的方法*******************************/
    /**
     * 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param $para 需要拼接的数组
     * return 拼接完成以后的字符串
     */
    private function createLinkstring($para) {
        $arg  = "";
        while (list ($key, $val) = each ($para)) {
            $arg.=$key."=".$val."&";
        }
        //去掉最后一个&字符
        $arg = substr($arg,0,count($arg)-2);

        //如果存在转义字符，那么去掉转义
        if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}

        return $arg;
    }
    /**
     * 对数组排序
     * @param $para 排序前的数组
     * return 排序后的数组
     */
    private function argSort($para) {
        ksort($para);
        reset($para);
        return $para;
    }

    /**
     * RSA签名
     * @param $data 待签名数据
     * @param $private_key_path 商户私钥文件路径
     * return 签名结果
     */
    private function rsaSign($data,$private_key_path) {
        $priKey = file_get_contents($private_key_path);
        $res = openssl_get_privatekey($priKey);
        openssl_sign($data, $sign, $res);
        openssl_free_key($res);
        //base64编码
        $sign = base64_encode($sign);
        return $sign;
    }



    /**RSA验签
     * $data待签名数据
     * $sign需要验签的签名
     * 验签用支付宝公钥
     * return 验签是否通过 bool值
     */
    private function verify($data, $sign)  {
        //读取支付宝公钥文件
        $pubKey = file_get_contents('key/alipay_public_key.pem');

        //转换为openssl格式密钥
        $res = openssl_get_publickey($pubKey);

        //调用openssl内置方法验签，返回bool值
        $result = (bool)openssl_verify($data, base64_decode($sign), $res);

        //释放资源
        openssl_free_key($res);

        //返回资源是否成功
        return $result;
    }
}